﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.Collections.Concurrent;

    public static class SessionStatic
    {

        public static ConcurrentDictionary < int , SessionData > cd = new ConcurrentDictionary < int , SessionData > () ;
        public static ConcurrentQueue < int > cq = new ConcurrentQueue < int > () ;
        public static int lastSession = int . MaxValue ;

        public static SessionData GetData ( int session ) //ts!
        {
            SessionData ret = null ;
            cd . TryGetValue ( session , out ret ) ;
            if ( ret != null ) {
                if ( ret . IsDead () ) {
                    cd . TryRemove ( session , out ret ) ;
                    ret = null ; }
                  else {
                    ret . LastUse = DateTime . Now ; } }
            return ( ret ) ;//kui ei leita, peaks olema null
        }

        public static int CreateSession () //ts!
        {
            bool result ;
            NewSession () ;
            result = cd . TryAdd ( lastSession , new SessionData () ) ;
            if ( ! result ) {
                SessionData temp ;
                while ( ! result ) {
                    cd . TryGetValue ( lastSession , out temp ) ;
                    if ( ! temp . IsDead () ) {
                        NewSession () ;
                        result = cd . TryAdd ( lastSession , new SessionData () ) ; }
                      else {
                        temp . RemoveData () ;
                        break ; } } }
            cq . Enqueue ( lastSession ) ;
            return ( lastSession ) ;
        }

        public static void DestroySession ( int session ) //ts!
        {
            SessionData temp ; cd . TryRemove ( session , out temp ) ;
        }

        private static void NewSession () //ts!
        {
            lastSession = ( lastSession == int . MaxValue ) ? 0 : ++ lastSession ;
            bool result ;
            int id ;
            result = cq . TryPeek ( out id ) ;
            SessionData temp = null ;
            while ( result ) {
                result = cd . TryGetValue ( id , out temp ) ;
                if ( ! result ) {
                    result = InlNewSess ( out id ) ; }
                  else {
                    result = temp . IsDead () ;
                    if ( result ) {
                        cd . TryRemove ( id , out temp ) ;
                        result = InlNewSess ( out id ) ; }
                      else {
                        result = cq . TryDequeue ( out id ) ;
                        if ( result ) {
                            cq . Enqueue ( id ) ;
                            result = false ; } } } }
        }

        private static bool InlNewSess ( out int id )
        {
            bool result ;
            cq . TryDequeue ( out id ) ;
            result = cq . TryPeek ( out id ) ;
            return ( result ) ;
        }

    }

